home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Franz PD / Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).zip / Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).adf / VideoText3.5 / source / cct.p < prev    next >
Text File  |  1994-04-01  |  9KB  |  263 lines

  1. UNIT cct; {$project vt }
  2. { Programmierung des CCT-Chips (Computer Controlled Teletext) SAA5246 }
  3.  
  4. INTERFACE; FROM vt USES global,i2c_serial;
  5.  
  6. PROCEDURE display_select(speicher: Byte);
  7. PROCEDURE TV_display(mode: Byte);
  8. FUNCTION VTstat: byte;
  9. PROCEDURE sperren(speicher: Byte);
  10. PROCEDURE anfordern(speicher: Byte; page, subpage: Integer; _mask: Str);
  11. PROCEDURE init_CCT;
  12. FUNCTION seite_da(speicher: Byte): Boolean;
  13. PROCEDURE gettime(speicher: Byte; VAR zeit: Str80);
  14. PROCEDURE gethead(speicher: Byte; VAR head: Str80);
  15. PROCEDURE getpage(speicher: Byte; seite: p_onepage; ganz: Boolean);
  16.  
  17. { ---------------------------------------------------------------------- }
  18.  
  19. IMPLEMENTATION;
  20. {$opt b-}
  21.  
  22. CONST SAA5246 = $22;
  23.       PBLF = $20;
  24.       DOCARE =  $10;
  25.       NOTHOLD = $08;
  26.       SERMAG = $0800; { C11 }
  27.  
  28. VAR i2cdata: Array[1..20] of Byte;    { kleiner Puffer für Kommandos }
  29.  
  30. PROCEDURE display_select{(speicher: Byte)};
  31. { Einen der 8 Seitenspeicher zur Anzeige auswählen }
  32. begin
  33.   setregister(SAA5246,4,speicher);
  34. end;
  35.  
  36. PROCEDURE TV_display{(mode: Byte)};
  37. { Art der Anzeige am Fernseher auswählen. }
  38. begin
  39.   i2cdata[1] := 5;
  40.   case mode of
  41.     2: { Normalseiten bildfüllend, Schlagzeilen als Boxen }
  42.       begin  i2cdata[2] := %11001100; i2cdata[3] := %01001111; end;
  43.     1: { Normalseiten als Boxen, Schlagzeilen transparent }
  44.       begin  i2cdata[2] := %11001111; i2cdata[3] := %00001111; end;
  45.     otherwise  { Anzeige aus }
  46.       begin  i2cdata[2] := %00000011; i2cdata[3] := %00000011; end;
  47.   end;
  48.   i2cdata[4] := %00000111;
  49.   i2cbusIO(SAA5246,^i2cdata,4);
  50. end;
  51.  
  52. FUNCTION VTstat{: byte};
  53. { Liest aus dem CCT das Register R11B. Bedeutung: bit0 - Videosignal vorh., }
  54. { bit1 - Textsignal vorh., bit2-5 - ROM-Version }
  55. begin
  56.   setregister(SAA5246,0,%00000001);   { R11B aktivieren }
  57.   VTstat := getregister(SAA5246,11);    { Status lesen }
  58.   setregister(SAA5246,0,%00000000);   { R11 aktivieren }
  59. end;
  60.  
  61. PROCEDURE sperren{(speicher: Byte)};
  62. { Seitensuche eines Empfangskreises anhalten, damit nicht evtl. niederpriore }
  63. { Empfangskreise behindert werden. Die Sperre wird bei Programmierung einer }
  64. { neuen Seitenanforderung automatisch aufgehoben. }
  65. begin
  66.   i2cdata[1] := 2;
  67.   i2cdata[2] := speicher*16;
  68.   i2cdata[3] := 0;
  69.   i2cbusIO(SAA5246,^i2cdata,3);
  70. end;
  71.  
  72. PROCEDURE anfordern{(speicher: Byte; page, subpage: Integer; _mask: Str)};
  73. { Einlesen einer Seite in einen Seitenspeicher 0..7 anfordern, Unterseite nur }
  74. { direkt anfordern, wenn subpage <> 0 }
  75. { <_mask> ist ein dreistelliger String, wo ein '*' steht, wird in der }
  76. { entsprechenden Ziffer der angeforderten Seitennummer das DOCARE-Bit }
  77. { gelöscht. }
  78. VAR lauf: integer;
  79.     mask: String[10];
  80. begin
  81.   mask := _mask;
  82.   { Seitenanforderung beschreiben: }
  83.   i2cdata[1] := 2;
  84.   i2cdata[2] := speicher*16;
  85.   i2cdata[3] := ((page div 100) mod 8) OR NOTHOLD;
  86.   i2cdata[4] := (page div 10) mod 10;
  87.   i2cdata[5] := page mod 10;
  88.   if page <> 0 then
  89.     for lauf := 3 to 5 do
  90.       if mask[lauf-2]<>'*' then
  91.         i2cdata[lauf] := i2cdata[lauf] or DOCARE;
  92.   i2cdata[6] := subpage div 1000;
  93.   i2cdata[7] := (subpage div 100) mod 10;
  94.   i2cdata[8] := (subpage div 10) mod 10;
  95.   i2cdata[9] := subpage mod 10;
  96.   if subpage <> 0 then
  97.     for lauf := 6 to 9 do  i2cdata[lauf] := i2cdata[lauf] or DOCARE;
  98.   i2cbusIO(SAA5246,^i2cdata,9)
  99. end;
  100.  
  101. PROCEDURE init_CCT;
  102. var i: byte;
  103. begin
  104.   { Wichtig in R1: bit5 - ACQ OFF, Decoder-NotAus; bit2 - TCS ON, }
  105.   { RGB-Ausgangssignal wird mit Fernsehbild synchronisiert. }
  106.   setregister(SAA5246,1,%00000100);
  107.   { Seitensuche sperren: }
  108.   for i := 0 to maxactive-1 do  sperren(i);
  109.   { alle Seitenspeicher löschen: }
  110.   for i := 0 to 7 do begin
  111.     setregister(SAA5246,8,%00001000 or i); delay(2);
  112.     { Löschvorgang dauert bis zu 22 ms, darum mal jeweils 40 ms warten. }
  113.   end;
  114.   { R11 aktivieren }
  115.   setregister(SAA5246,0,%00000000);
  116.   { Fernsehdarstellung einschalten }
  117.   display_select(0);
  118.   TV_display(2);
  119. end;
  120.  
  121. FUNCTION seite_da{(speicher: Byte): Boolean};
  122. { Überprüft, ob die für einen Speicher 0..7 angeforderte Seite bereits }
  123. { eingetroffen ist. Das Statusflag PBLF, das in diesem Fall gelöscht ist, }
  124. { muß danach wieder gesetzt werden. Das geschieht entweder implizit beim }
  125. { Programmieren einer neuen Seitenanforderung oder explizit durch }
  126. { Schreibzugriff, in diesem Programm in getpage(). }
  127. { Problem: das Statusflag PBLF bezieht sich auf den Empfang der Kopfzeile, }
  128. { nicht etwa den Empfang der kompletten Seite. Genauer gesagt: für letzteres }
  129. { existiert überhaupt kein Statusflag! }
  130. { Nun ist das nicht ganz so tragisch, nach Empfang der Kopfzeile kann man }
  131. { bereits bedenkenlos die Statuszeile 25 mit Steuerbits und Seitennummer }
  132. { lesen. Und in vielen Fällen geht es sogar gut, sofort mit dem Einlesen }
  133. { der gesamten Seite zu beginnen, da sich nämlich maximal 11 Seiten pro }
  134. { Sekunde über den I²C-Bus schaufeln lassen, während der Videotext selbst }
  135. { mit ca. 13 Seiten pro Sekunde einrollt: Die noch leere Seite wird }
  136. { schneller aufgefüllt, als sie ausgelesen werden kann. }
  137. { Probleme entstehen natürlich, wenn der Empfang der VT-Seite länger als }
  138. { ca. 1/10 s dauert. Das ist möglich, wenn der Sender nicht alle zur }
  139. { VT-Übertragung zulässigen Rasterzeilen ausnutzt, oder wenn er gar den }
  140. { Magazin-gemischten Übertragungsmodus verwendet. Letzteres ist aber an }
  141. { einem Statusflag (C11) vom Programm aus erkennbar, hm ... }
  142. begin
  143.   seite_da := false;
  144.   { Byte 9 der Statuszeile (Zeile 25) adressieren ... }
  145.   i2cdata[1] := 8;
  146.   i2cdata[2] := speicher;
  147.   i2cdata[3] := 25; i2cdata[4] := 9;
  148.   i2cbusIO(SAA5246,^i2cdata,4);
  149.   if i2c_status<>0 then
  150.     exit; { Schreibfehler }
  151.   { ... und auslesen: }
  152.   i2cbusIO(SAA5246,^i2cdata,-1);
  153.   if i2c_status<>0 then
  154.     exit; { Lesefehler }
  155.   seite_da := (i2cdata[1] AND PBLF)=0;
  156. end;
  157.  
  158. PROCEDURE gettime{(speicher: Byte; VAR zeit: Str80)};
  159. { liest aus einer Speicherseite 0..7 des CCT-Bausteins die Uhrzeit }
  160. var i: integer;
  161. begin
  162.   zeit := '00:00:00';
  163.   { Uhrzeit aus der Seite im CCT lesen: Zeile 0, Spalte 32 }
  164.   i2cdata[1] := 8;
  165.   i2cdata[2] := speicher;
  166.   i2cdata[3] := 0; i2cdata[4] := 32;
  167.   i2cbusIO(SAA5246,^i2cdata,4);
  168.   if i2c_status<>0 then
  169.     exit; { Schreibfehler }
  170.   { Uhrzeit lesen: }
  171.   i2cbusIO(SAA5246,^i2cdata,-8);
  172.   if i2c_status<>0 then
  173.     exit; { Lesefehler }
  174.   for i := 1 to 8 do
  175.     IF i2cdata[i] IN [32..127] THEN zeit[i] := chr(i2cdata[i]);
  176. end;
  177.  
  178. PROCEDURE gethead{(speicher: Byte; VAR head: Str80)};
  179. { liest die 24 Byte Titelzeile zwischen Statusfeld und Uhrzeit }
  180. var i: integer;
  181. begin
  182.   head := '';
  183.   { Seitenspeicher addressieren: Zeile 0, Spalte 8 }
  184.   i2cdata[1] := 8;
  185.   i2cdata[2] := speicher;
  186.   i2cdata[3] := 0; i2cdata[4] := 8;
  187.   i2cbusIO(SAA5246,^i2cdata,4);
  188.   if i2c_status<>0 then
  189.     exit; { Schreibfehler }
  190.   { Zeile lesen: }
  191.   i2cbusIO(SAA5246,^head,-24);
  192.   if i2c_status<>0 then
  193.     exit; { Lesefehler }
  194.   for i := 1 to 24 do
  195.     IF NOT (ord(head[i]) IN [32..127]) THEN head[i] := ' ';
  196.   head[25] := #0;
  197. end;
  198.  
  199. PROCEDURE getpage{(speicher: Byte; seite: p_onepage; ganz: Boolean)};
  200. { Liest eine Speicherseite (0..7) aus dem CCT-Baustein aus und speichert }
  201. { diese Seite im Amiga. Für <ganz>=false werden nur die Statusinformationen }
  202. { aus Zeile 25 gelesen. }
  203. { Abschließend wird das Statusflag PBLF wieder gesetzt! }
  204. VAR i,h: Integer;
  205.     status: ARRAY [0..9] OF Byte;
  206.     s: str80;
  207. BEGIN
  208.   { Status aus der Seite im CCT lesen: Zeile 25, Spalte 0 }
  209.   i2cdata[1] := 8;
  210.   i2cdata[2] := speicher;
  211.   i2cdata[3] := 25; i2cdata[4] := 0;
  212.   i2cbusIO(SAA5246,^i2cdata,4);
  213.   if i2c_status<>0 then
  214.     exit; { Schreibfehler }
  215.   i2cbusIO(SAA5246,^status,-10);
  216.   if i2c_status<>0 then
  217.     exit; { Lesefehler }
  218.   seite^.pg := (status[0] and $F) + 10*(status[1] and $F) + 100*(status[8] and $7);
  219.   if seite^.pg<100 then seite^.pg := seite^.pg + 800;
  220.   seite^.sp := (status[2] and $F) + 10 * (status[3] and $7)
  221.       + 100 * (status[4] and $F) + 1000 * (status[5] and $3);
  222.   seite^.cbits := (status[3] AND $08) SHL 1   { C4 }
  223.                 + (status[5] AND $0C) SHL 3   { C5, C6 }
  224.                 + (status[6] AND $0F) SHL 7   { C7, C8, C9, C10 }
  225.                 + (status[7] AND $0F) SHL 11  { C11, C12..C14 }
  226.   if ganz then begin
  227.     { Seite aus CCT lesen. Richtigen Speicher, Zeile 0, Spalte 0 adressieren: }
  228.     i2cdata[1] := 8;
  229.     i2cdata[2] := speicher;
  230.     i2cdata[3] := 0; i2cdata[4] := 0;
  231.     i2cbusIO(SAA5246,^i2cdata,4);
  232.     if i2c_status<>0 then begin
  233.       exit; { Schreibfehler }
  234.     end;
  235.     { Seite einlesen: }
  236.     i2cbusIO(SAA5246,^seite^.chars,-960);
  237.     if i2c_status<>0 then begin
  238.       exit; { Lesefehler }
  239.     end;
  240.     { in den freien Anfang der 1. Zeile die Unterseitennummer eintragen }
  241.     seite^.chars[1] := ord('(');
  242.     seite^.chars[2] := (status[5] and $3)+ord('0');
  243.     seite^.chars[3] := (status[4] and $F)+ord('0');
  244.     seite^.chars[4] := (status[3] and $7)+ord('0');
  245.     seite^.chars[5] := (status[2] and $F)+ord('0');
  246.     seite^.chars[6] := ord(')');
  247.     seite^.chars[7] := ord(' ');
  248.     IF status[7] AND $01=0 THEN BEGIN  { C11=0: Magazin-gemischte Übertragung, }
  249.       seite^.chars[1] := ord('<');  { Modus für den Benutzer erkennbar machen }
  250.       seite^.chars[6] := ord('>');
  251.     END;
  252.     { aus dem zur Anzeige aktivierten Seitenspeicher die Uhrzeit holen: }
  253.     if speicher<>aktspeicher then begin
  254.       gettime(aktspeicher,s);
  255.       for i := 1 to 8 do
  256.         seite^.chars[31+i] := ord(s[i]);
  257.     END;
  258.   END;
  259. END;
  260.  
  261. BEGIN  { Initialisierungsteil }
  262. END.
  263.